<template>
  <div id="my-three"></div>
</template>

<script setup>
import { ref, shallowRef } from 'vue'
import * as THREE from 'three'
import { GridHelper } from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js';
import { onMounted, onUnmounted } from 'vue'

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
import GUI from 'lil-gui'//调色板
// 创建三维场景
const scene = new THREE.Scene();


///////////////////////////////////////////////////////////////////////////////////////////添加圆柱体房间代码，无需房间注释即可,同时将'无需房间的代码'的代码打开
// 在场景创建后添加圆柱体房间
// const roomHeight = 5000; // 房间高度
// const roomRadius = 5000; // 半径与地面相同(地面尺寸1000，半径500)
// //创建圆柱体墙壁(去掉顶部和底部)
// const roomGeometry = new THREE.CylinderGeometry(
//   roomRadius,
//   roomRadius,
//   roomHeight,
//   64,
//   1,
//   true, // 不渲染底面
//   false // 不渲染顶面
// );

// // 添加天花板
// const ceilingGeometry = new THREE.CircleGeometry(roomRadius, 64);
// const ceilingMaterial = new THREE.MeshStandardMaterial({
//   color: '#ffffff',
//   side: THREE.DoubleSide,
//   transparent: true,
//   opacity: 1,    // 提高透明度
//   roughness: 0.1,  // 表面光滑度
//   metalness: 0.5   // 轻微金属感
// });

const roomMaterial = new THREE.MeshStandardMaterial({
  color: '#ffffff',
  side: THREE.DoubleSide, // 双面渲染
  transparent: true,
  // opacity: 0.3, // 半透明效果
  roughness: 0.7,
  metalness: 0.1
});


// const room = new THREE.Mesh(roomGeometry, roomMaterial);



//添加光滑灰色的地面
// const groundGeometry = new THREE.PlaneGeometry(5000, 5000); // 地面大小
// const groundMaterial = new THREE.MeshStandardMaterial({
//   color: '#0099FF', // 灰色
//   roughness: 0.1,  // 表面光滑度
//   metalness: 0.5   // 轻微金属感
// });
// const ground = new THREE.Mesh(groundGeometry, groundMaterial);
// ground.rotation.x = -Math.PI / 2; // 旋转使平面水平
// ground.receiveShadow = true; // 允许接收阴影
// scene.add(ground);




// 创建透视相机
let width = window.innerWidth, height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000);
camera.position.set(50, 10, 100); // 设置相机位置
camera.lookAt(0, 10, 0);; // 设置相机朝向





// ==================== 灯光设置 ====================
//添加光源
const ambient = new THREE.AmbientLight('#ffffff', 1.5); // 环境光
scene.add(ambient);

// 1. 主灯光（Z轴方向）
const zAxisLight = new THREE.DirectionalLight(
  '#ffffff', // 灯光颜色（白色）
  2          // 光照强度
);
zAxisLight.position.set(0, camera.position.y, 150); // 灯光位置
zAxisLight.castShadow = true; // 启用阴影
zAxisLight.shadow.mapSize.width = 2048; // 阴影贴图宽度
zAxisLight.shadow.mapSize.height = 2048; // 阴影贴图高度
scene.add(zAxisLight);



// 创建WebGL渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  powerPreference: "high-performance" // 启用高性能模式
});
renderer.setSize(width, height);
// renderer.shadowMap.enabled = true; // 启用阴影渲染
renderer.physicallyCorrectLights = true; // 物理正确光照
renderer.outputEncoding = THREE.SRGBColorSpace; // 使用sRGB色彩空间
renderer.toneMapping = THREE.ACESFilmicToneMapping; // 电影级色调映射
renderer.toneMappingExposure = 1.2; // 增加曝光值
renderer.render(scene, camera);

// 创建控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', () => {
  renderer.render(scene, camera); // 每次控制变化时重新渲染
});


// 初始化后期处理器
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));

// 添加辉光效果
const bloomPass = new UnrealBloomPass(
  new THREE.Vector2(width, height),
  1.5, // 强度
  0.4, // 半径
  0.85  // 阈值
);
composer.addPass(bloomPass);



// 窗口大小变化处理函数
const handleResize = () => {
  // 更新窗口尺寸
  width = window.innerWidth;
  height = window.innerHeight;

  // 更新相机参数
  camera.aspect = width / height;
  camera.updateProjectionMatrix();

  // 更新渲染器尺寸
  renderer.setSize(width, height);

  // 重新渲染场景
  renderer.render(scene, camera);
};

// 添加动画循环函数---用于解决刷新之后自定义模型不显示的问题
function animate() {
  requestAnimationFrame(animate);
  controls.update(); // 只在需要时更新控制器
  composer.render();
  renderer.render(scene, camera);
}






// 定义事件处理函数引用
const targetMesh = shallowRef(null); //用于接收组件----使用shallowRef定义是因为使用ref定义会被转为Proxy(Mesh)对象影响了贴图操作
const currentModel = ref(null) // 用于跟踪当前模型
/**
 * 加载并设置3D模型的函数
 */
const loadModel = () => {
  // // 创建FBX加载器实例
  const loader = new FBXLoader();
  loader.load('/models/fjhj.fbx', (object) => {
    scene.add(object);



    // 1. 计算模型尺寸和中心点
    const bbox = new THREE.Box3().setFromObject(object);
    const center = bbox.getCenter(new THREE.Vector3());
    const size = bbox.getSize(new THREE.Vector3());
    const maxDim = Math.max(size.x, size.y, size.z);

    // 2. 将模型中心移动到场景原点
    object.position.sub(center);

    // 3. 动态计算相机位置（核心修改）
    const cameraDistance = maxDim * 2; // 相机距离设为模型最大尺寸的2倍
    camera.position.set(0, maxDim * 0.5, cameraDistance); // 相机抬高到模型高度一半
    // 调整相机远平面
    camera.far = 100000; // 增大远平面距离
    camera.updateProjectionMatrix();

    // 4. 调整控制器参数
    controls.target.set(0, 0, 0); // 看向场景中心
    // controls.minDistance = maxDim * 0.5; // 最小缩放距离
    // controls.maxDistance = maxDim * 5;  // 最大缩放距离
    controls.update();

    // 5. 调整坐标轴帮助器大小
    // scene.remove(axesHelper);
    const axesHelper = new THREE.AxesHelper(maxDim);
    scene.add(axesHelper);

    //   // 刷新回显操作
    animate();

  },
    undefined, // 加载进度回调（未使用）
    (error) => { // 模型加载错误处理
      console.error('FBX模型加载错误:', error);
    });
};

// 在组件卸载时执行清理
onUnmounted(() => {
  // 清理材质资源
  if (targetMesh.value && targetMesh.value.material) {
    targetMesh.value.material.dispose();
  }
});

onMounted(() => {
  loadModel();
  // initGUI()
  document.getElementById('my-three')?.appendChild(renderer.domElement);
  // 添加窗口大小变化监听
  window.addEventListener('resize', handleResize);
});

</script>

<style>
body {
  margin: 0;
  padding: 0;
}

.my-three {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
</style>